﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

using Palsta.Core.data;

namespace Palsta.Core.action
{

    class ActionMap
    {
        #region Members

        Hashtable evalueJs = new Hashtable();           //String, String
        Hashtable onChangeRelation = new Hashtable();   //String, ArrayList<String>
        private int domId = 1;
        private int conditionId = 1;
        private int assignmentId = 1;
        private int dialogMsgId = 1;
        private int dialogExpId = 1;
        private int validationId = 1;
        private int caculationId = 1;
        private String initJs = "";

        // <FieldName, DomID>
        private Hashtable fieldDomId = new Hashtable();

        // <ID, JSBlock>  JS of Expression and Test
        private Hashtable expressionJs = new Hashtable();

        // <ConditionID, JSBlock>
        private Hashtable conditionJs = new Hashtable();

        // <AssignmentID, JSBlock>
        private Hashtable ruleActionJs = new Hashtable();

        // <ValidationID, JSBlock>
        private Hashtable validationJs = new Hashtable();

        // <CaculationID, JSBlock>
        private Hashtable caculationJs = new Hashtable();
        
        // <DomId, JSBlock> JS of Dom element
        private Hashtable evalueFieldJs = new Hashtable();
        private Hashtable affectAttributes = new Hashtable();   

        // <DomID, StringBuilder>
        private Hashtable onChangeJS = new Hashtable();

        #endregion

        #region Constructors

        #endregion

        #region Accessors

        public virtual Hashtable FieldDomId
        {
            get
            {
                return this.fieldDomId;
            }
        }

        public virtual Hashtable ExpressionJS
        {
            get
            {
                return this.expressionJs;
            }
        }

        public virtual Hashtable ConditionJS
        {
            get
            {
                return this.conditionJs;
            }
        }

        public virtual Hashtable RuleActionJS
        {
            get
            {
                return this.ruleActionJs;
            }
        }

        public virtual Hashtable ValidationJS
        {
            get
            {
                return this.validationJs;
            }
        }

        public virtual Hashtable CaculationJS
        {
            get
            {
                return this.caculationJs;
            }
        }

        public virtual Hashtable EvalueFieldJS
        {
            get
            {
                return this.evalueFieldJs;
            }
        }

        public virtual Hashtable OnChangeJS
        {
            get
            {
                return this.onChangeJS;
            }
        }

        public virtual String InitFunctionJS
        {
            get
            {
                return this.initJs;
            }
            set
            {
                this.initJs = value;
            }
        }

        #endregion

        #region Methods SetJS

        public void SetExpJs(int eid, JSBlock js)
        {
            JSBlock oriJs = (JSBlock)this.expressionJs[eid];
            if (oriJs == null)
            {
                this.expressionJs.Add(eid, js);
            }
            else
            {
                this.expressionJs[eid] = js;
            }
        }

        public void SetConditionJs(String conditionId, JSBlock js)
        {
            JSBlock ori = (JSBlock)this.conditionJs[conditionId];
            if (ori == null)
            {
                this.conditionJs.Add(conditionId, js);
            }
            else
            {
                this.conditionJs[conditionId] = js;
            }
        }

        public void SetRuleActionJs(String ruleActionId, JSBlock js)
        {
            JSBlock ori = (JSBlock)this.ruleActionJs[ruleActionId];
            if (ori == null)
            {
                this.ruleActionJs.Add(ruleActionId, js);
            }
            else
            {
                this.ruleActionJs[ruleActionId] = js;
            }
        }

        public void SetValidationJs(String validationId, JSBlock js)
        {
            JSBlock ori = (JSBlock)this.validationJs[validationId];
            if (ori == null)
            {
                this.validationJs.Add(validationId, js);
            }
            else
            {
                this.validationJs[validationId] = js;
            }
        }

        public void SetCaculationJs(String caculationId, JSBlock js)
        {
            JSBlock ori = (JSBlock)this.validationJs[caculationId];
            if (ori == null)
            {
                this.caculationJs.Add(caculationId, js);
            }
            else
            {
                this.caculationJs[caculationId] = js;
            }
        }

        public void SetEvalueFieldJs(String domId, JSBlock js)
        {
            JSBlock oriJs = (JSBlock)this.evalueFieldJs[domId];
            if (oriJs == null)
            {
                this.evalueFieldJs.Add(domId, js);
            }
            else
            {
                this.evalueFieldJs[domId] = js;
            }
        }

        public void AddOnChangeJS(String domId, String js)
        {
            StringBuilder sb = (StringBuilder)this.onChangeJS[domId];
            if (sb == null)
            {
                sb = new StringBuilder();
                this.onChangeJS.Add(domId, sb);
            }
            if (sb.Length > 0)
            {
                sb.Append("\r\n");
            }
            sb.Append("    ").Append(js);
        }



        #endregion

        #region Methods Generate Id

        public String GenerateDomId()
        {
            return "" + (this.domId++).ToString("D4");
        }

        public String GenerateConditionId()
        {
            return "condition_" + (this.conditionId++).ToString("D4");
        }

        public String GenerateAssignmentId()
        {
            return "assignment_" + (this.assignmentId++).ToString("D4");
        }

        public String GenerateDialogMsgId()
        {
            return "dialogMsg_" + (this.dialogMsgId++).ToString("D4");
        }

        public String GenerateDialogExpId()
        {
            return "dialogExp_" + (this.dialogExpId++).ToString("D4");
        }

        public String GenerateValidationId()
        {
            return "validation_" + (this.validationId++).ToString("D4");
        }

        public String GenerateCaculationId()
        {
            return "caculation_" + (this.caculationId++).ToString("D4");
        }
        
        #endregion

        #region Method Get JS function list

        public ArrayList GetConditionFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.conditionJs.GetEnumerator();
            while (i.MoveNext())
            {
                String js = "function " + (String)i.Key + "()\r\n{\r\n" + ((JSBlock)i.Value).JS + "\r\n}\r\n";
                list.Add(js);
            }
            return list;
        }

        public ArrayList GetAssignmentFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.ruleActionJs.GetEnumerator();
            while (i.MoveNext())
            {
                String js = "function " + (String)i.Key + "()\r\n{\r\n" + ((JSBlock)i.Value).JS + "\r\n}\r\n";
                list.Add(js);
            }
            return list;
        }

        public ArrayList GetValidationFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.validationJs.GetEnumerator();
            while (i.MoveNext())
            {
                String js = "function " + (String)i.Key + "()\r\n{\r\n" + ((JSBlock)i.Value).JS + "\r\n}\r\n";
                list.Add(js);
            }
            return list;
        }

        public ArrayList GetCaculationFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.caculationJs.GetEnumerator();
            while (i.MoveNext())
            {
                String js = "function " + (String)i.Key + "()\r\n{\r\n" + ((JSBlock)i.Value).JS + "\r\n}\r\n";
                list.Add(js);
            }
            return list;
        }

        public ArrayList GetEvalFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.evalueFieldJs.GetEnumerator();
            while (i.MoveNext())
            {
                JSBlock jsb = (JSBlock)i.Value;
                ArrayList attrs = (ArrayList)this.affectAttributes[(String)i.Key];

                StringBuilder js = new StringBuilder();
                js.Append("function eval_").Append((String)i.Key).Append("()\r\n{\r\n");
                if (attrs != null)
                {
                    foreach (JSBlock initJs in attrs)
                    {
                        js.Append("    ").Append(initJs.JS).Append(";\r\n");
                    }
                }
                js.Append("    return ").Append(jsb.JS).Append(";\r\n}\r\n");
                list.Add(js.ToString());
            }
            list.Sort();
            return list;
        }

        public ArrayList GetOnChangeFunJs()
        {
            ArrayList list = new ArrayList();
            IDictionaryEnumerator i = this.onChangeJS.GetEnumerator();
            while (i.MoveNext())
            {
                String js = "function onChange_" + (String)i.Key + "()\r\n{\r\n" + ((StringBuilder)i.Value).ToString() + "\r\n}\r\n";
                list.Add(js);
            }
            list.Sort();
            return list;
        }

        #endregion

        
        
        #region Method

        public void AddAffectAttribute(String domId, JSBlock initAttrExp)
        {
            ArrayList list = (ArrayList)this.affectAttributes[domId];
            if (list == null)
            {
                list = new ArrayList();
                this.affectAttributes.Add(domId, list);
            }
            bool exists = false;
            for (int i = 0; i < list.Count; i++)
            {
                if (initAttrExp.JS.Equals(((JSBlock)list[i]).JS))
                {
                    exists = true;
                    break;
                }
            }
            if (!exists)
            {
                list.Add(initAttrExp);
            }
        }

        public ArrayList GetAffectAttribute(String domId)
        {
            StringBuilder js = new StringBuilder();
            return (ArrayList)onChangeRelation[domId];
        }



        #endregion

        #region Override Operators

        #endregion

        #region Static Methods

        #endregion

        




        //for (int i = 0; i < myAffectList.Count; i++)
        //{
        //    String attr = (String)affectAttrs[i];
        //    String value = InfoPathXml.GetNodeAttr(domXmlNode, attr);
        //    if (value == null)
        //    {
        //        evalueJs.Append("removeAttribute('").Append(domId).Append("','").Append(attr).Append("');\r\n");
        //    }
        //    else
        //    {
        //        evalueJs.Append("setAttribute('").Append(domId).Append("','")
        //            .Append(attr).Append("','")
        //            .Append(value).Append("');\r\n");
        //    }
        //}
    }
}
